﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.DAL
{
    public class TiposActivosFactory
    {

        //Inserta un tipo de activo en la base de conocimiento
        public static void InsertarTipoActivo(TiposActivos t)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToTiposActivosEstablecer(t);
            agenteBD.SaveChanges();
        }

        //Inserta un tipo de activo a través de su nombre
        public static void InsertarTipoActivo(string TipoActivoTexto)
        {
            TiposActivos TipoActivoNuevo = new TiposActivos();
            TipoActivoNuevo.TipoActivo = TipoActivoTexto;
            TipoActivoNuevo.Actual = true;
            TiposActivosFactory.InsertarTipoActivo(TipoActivoNuevo);
        }

        //Indica si un tipo de activo está en la base de conocimiento a través de su nombre
        public static bool EstaTipoActivo(String NTipoActivo)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> TipoActivoIgual = from TipoActivo in agenteBD.TiposActivosEstablecer
                                                 select TipoActivo.TipoActivo;
            foreach (String v in TipoActivoIgual)
            {
                if (NTipoActivo.Equals(v.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    esta = true;
                }
            }
            return esta;
        }

        //Número de tipos de activos totales en la base de conocimiento
        public static int TiposActivosTotales()
        {
            int numeroTiposActivos = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<TiposActivos> TipActTotal = from TipAc in agenteBD.TiposActivosEstablecer
                                                   select TipAc;
            foreach (TiposActivos Tip in TipActTotal)
            {
                numeroTiposActivos++;
            }
            return numeroTiposActivos;
        }

        //Devuelve el identificador de un tipo de activo según su nombre
        public static int BuscarIdTipoActivo(String NombreTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdTipoActivoSelec = from TipoActivo in agenteBD.TiposActivosEstablecer
                                                where TipoActivo.TipoActivo == NombreTipoActivo
                                                select TipoActivo.IdTipoActivo;

            if (IdTipoActivoSelec.Count() == 0)
            {
                return -1;
            }
            else
            {
                return IdTipoActivoSelec.First();
            }
        }

        //Devuelve el nombre de un tipo de activo según su identificador
        public static String RecogeNombreTipoActivo(int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> IdTipoActivoSelec = from TipoActivo in agenteBD.TiposActivosEstablecer
                                                   where TipoActivo.IdTipoActivo == IdTipoActivo
                                                   select TipoActivo.TipoActivo;

            if (IdTipoActivoSelec.Count() == 0)
            {
                return "";
            }
            else
            {
                return IdTipoActivoSelec.First();
            }
        }



        //Método que recoge el número activos actuales de una empresa por Tipo de Activo
        public static List<int> NumActivosTipActivoEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumActivTipActEmp = new List<int>();
            IQueryable<int> IdTiposActivos = from NTipAct in agenteBD.TiposActivosEstablecer
                                             select NTipAct.IdTipoActivo;
            foreach (int IdTipoActivo in IdTiposActivos)
            {
                int NTipActivoEmp = ActivosEmpresaFactory.NumeroActivosTipoActivoEmpresa(IdEmpresa, IdTipoActivo);
                LNumActivTipActEmp.Add(NTipActivoEmp);
            }
            return LNumActivTipActEmp;
        }

        //Método para recoger los Id's de los Tipo de Activo (la mitad de ellos) para el gráfico del Informe sobre
        //relaciones seleccionadas por una empresa
        public static List<int> RecogeIdTipoActivo1de2()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumActivTipActEmp = new List<int>();
            List<int> LIdTiposActivos1de2 = (from NTipAct in agenteBD.TiposActivosEstablecer
                                             where NTipAct.IdTipoActivo < 12
                                             select NTipAct.IdTipoActivo).ToList();
            return LIdTiposActivos1de2;
        }

        //Método para recoger los Id's de los Tipo de Activo (la otra mitad de ellos) para el gráfico del Informe sobre
        //relaciones seleccionadas por una empresa
        public static List<int> RecogeIdTipoActivo2de2()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumActivTipActEmp = new List<int>();
            List<int> LIdTiposActivos2de2 = (from NTipAct in agenteBD.TiposActivosEstablecer
                                             where NTipAct.IdTipoActivo > 11
                                             select NTipAct.IdTipoActivo).ToList();
            return LIdTiposActivos2de2;
        }


        //Recoge todos los tipos de activos actualmente disponibles en la base de conocimiento
        public static IQueryable<TiposActivos> RecogeTiposActivos()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<TiposActivos> TiposActivos = from TipAct in agenteBD.TiposActivosEstablecer
                                                    where TipAct.Actual == true
                                                    select TipAct;
            if (TiposActivos.Count() == 0)
            {
                return null;
            }
            return TiposActivos;
        }

        //Recoge los tipos de activos disponibles en la base de conocimiento, cuyo nombre contenga la secuencia de TextoBuscar
        public static IQueryable<TiposActivos> RecogeTiposActivosTexto(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<TiposActivos> Vulnerabilidades = from t in agenteBD.TiposActivosEstablecer
                                                        where t.TipoActivo.Contains(TextoBuscar) && t.Actual == true
                                                        select t;
            if (Vulnerabilidades.Count() == 0)
            {
                return null;
            }
            return Vulnerabilidades.OrderBy(t => t.TipoActivo);
        }

        //Actualiza los valores de un tipo de activo
        public static void ActualizaTipoActivo(int IdTipoActivo, string TipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var TipoActivoAct = (from TipAct in agenteBD.TiposActivosEstablecer
                                 where TipAct.IdTipoActivo == IdTipoActivo
                                 select TipAct).Single();
            TipoActivoAct.TipoActivo = TipoActivo;
            agenteBD.SaveChanges();
        }

        //Método que elimina un Tipo de Activo, así como todas las tuplas relacionadas en la Base de Datos
        public static void EliminaTipoActivo(int IdTipoActivo)
        {
            //Se pone el tipo de activo seleccionado con actual a false
            EliminaTipoAct(IdTipoActivo);
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Vulnerabilidades por Tipo de Activo
            List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorTipAct = new List<Matriz_TiposActivosVulnerabilidades>();
            //Lista de Relaciones Tipo Activo - Amenazas - Criterios de Riesgo por relaciones de ese tipo
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorTipAct = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            List<InstanciaTiposActivosVulnerabilidades> LInstPorRelTipActVul = new List<InstanciaTiposActivosVulnerabilidades>();
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Vulnerabilidades
            LRelTipActVulnPorTipAct = Matriz_TiposActivosVulnerabilidadesFactory.EliminaRelacionesTipActVulnPorTipoActivo(IdTipoActivo);
            LRelTipActAmenCritPorTipAct = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.EliminaRelacionesPorTipoActivo(IdTipoActivo);
            //Nivel 2 de Dependencia
            //Instancia Tipo Activo - Vulnerabilidades
            if (LRelTipActVulnPorTipAct.Count != 0)
            {
                //Instancia_TiposActivosAmenazasCriteriosRiesgo
                LInstPorRelTipActVul = InstanciaTiposActivosVulnerabilidadesFactory.EliminaInstanciaPorRelacTipActVuln(LRelTipActVulnPorTipAct);
            }
            if (LRelTipActAmenCritPorTipAct.Count != 0)
            {
                //Instancia Tipo Activo - Amenaza - Criterio de Riesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorTipAct);
            }
        }

        //Método que elimina (borrado lógico) a un tipo de activo en la base de conocimiento
        private static void EliminaTipoAct(int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            TiposActivos TipoActElim = (from TipAct in agenteBD.TiposActivosEstablecer
                                        where TipAct.IdTipoActivo == IdTipoActivo
                                        select TipAct).Single();
            TipoActElim.Actual = false;
            agenteBD.SaveChanges();
        }

        //Método que Restaura el conocimiento asociado a una lista de Tipos de Activos a través de sus Ids
        public static void RestauraTipoActivo(List<int> LTiposActivos)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdTipoActivo in LTiposActivos)
            {
                TiposActivos TipoActivoRestaurar = (from TipAct in agenteBD.TiposActivosEstablecer
                                                    where TipAct.IdTipoActivo == IdTipoActivo
                                                    select TipAct).Single();
                TipoActivoRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Vulnerabilidades por Criterio de Riesgo
            List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorTipAct = new List<Matriz_TiposActivosVulnerabilidades>();
            //Lista de Instancia Tipos Activos - Vulnerabilidades por relaciones de ese tipo
            List<InstanciaTiposActivosVulnerabilidades> LInstPorRelTipActVul = new List<InstanciaTiposActivosVulnerabilidades>();
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Amenazas
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorTipAct = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            //Lista de Instancia Tipos Activos - Amenazas - Criterios de Riesgo por relaciones Tipos Activos - Amenazas - Criterios Riesgo
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Vulnerabilidades
            LRelTipActVulnPorTipAct = Matriz_TiposActivosVulnerabilidadesFactory.RestauraRelacionesPorTipoActivo(LTiposActivos);
            LRelTipActAmenCritPorTipAct = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.RestauraRelacionesPorTipoActivo(LTiposActivos);
            //Nivel 2 de Dependencia
            if (LRelTipActVulnPorTipAct.Count != 0)
            {
                //Instancia_TiposActivosVulnerabilidades
                LInstPorRelTipActVul = InstanciaTiposActivosVulnerabilidadesFactory.RestauraInstanciaPorRelacTipActVuln(LRelTipActVulnPorTipAct);
            }
            if (LRelTipActAmenCritPorTipAct.Count != 0)
            {
                //Instancia_TiposActivosAmenazasCriteriosRiesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.RestauraInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorTipAct);
            }

        }

        //Método que restaura una lista de tipos de activos en la base de conocimiento
        internal static void RestauraTipoActivoPorRelaciones(List<int> LIdsTiposActivos)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdTipoActivo in LIdsTiposActivos)
            {
                //Restauramos los Tipos de Activos
                TiposActivos TipActRestaurar = (from TipAct in agenteBD.TiposActivosEstablecer
                                                where TipAct.IdTipoActivo == IdTipoActivo
                                                select TipAct).Single();
                TipActRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
        }

        //Devuelve una lista con el conjunto de tipos de activos que haya en la base de conocimiento
        public static List<String> ListaTiposActivos()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NTiposActivo = from TipoAct in agenteBD.TiposActivosEstablecer
                                              select TipoAct.TipoActivo;
            List<String> LTipoActivo = new List<String>();
            if (NTiposActivo.Count() != 0)
            {
                foreach (String TipoActivo in NTiposActivo)
                {
                    LTipoActivo.Add(TipoActivo);
                }
                return LTipoActivo;
            }
            else
            {
                //Fallo, devuelve null
                return null;
            }
        }

        //Método que recoge el número de activos por Tipo Activo de un Informe dado
        public static List<int> NumActivosTipActivoInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumActivTipActEmp = new List<int>();
            IQueryable<int> IdTiposActivos = from NTipAct in agenteBD.TiposActivosEstablecer
                                             select NTipAct.IdTipoActivo;
            foreach (int IdTipoActivo in IdTiposActivos)
            {
                int NTipActivoEmp = ActivosInformeFactory.NumeroActivosTipoActivoInforme(IdInforme, IdTipoActivo);
                LNumActivTipActEmp.Add(NTipActivoEmp);
            }
            return LNumActivTipActEmp;
        }

        //Devuelve el número de tipos de activos actualmente disponibles en la base de conocimiento
        public static int NumeroTiposActivos()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTiposActivos = (from TipAct in agenteBD.TiposActivosEstablecer
                                 where TipAct.Actual == true
                                 select TipAct).Count();
            return NTiposActivos;
        }

        //Devuelve el conjunto de los tipos de activos actualmente deshabilitados en la base de conocimiento
        public static List<TiposActivos> TiposActivosEliminados()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<TiposActivos> LTiposAmenazas = new List<TiposActivos>();
            IQueryable<TiposActivos> TipAmenQuery = (from t in agenteBD.TiposActivosEstablecer
                                                     where t.Actual == false
                                                     orderby t.IdTipoActivo
                                                     select t).Distinct();
            if (TipAmenQuery.Count() != 0)
            {
                LTiposAmenazas = TipAmenQuery.ToList();
            }
            return LTiposAmenazas;
        }

        //Devuelve el conjunto de los tipos de activos deshabilitados en la base de conocimiento cuyos nombres coincidan con TextoBuscar
        public static List<TiposActivos> TiposActivosEliminadosPorTipoActivo(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<TiposActivos> LTiposAmenazas = new List<TiposActivos>();
            IQueryable<TiposActivos> TipAmenQuery = (from t in agenteBD.TiposActivosEstablecer
                                                     where t.Actual == false && t.TipoActivo.Contains(TextoBuscar)
                                                     orderby t.IdTipoActivo
                                                     select t).Distinct();
            if (TipAmenQuery.Count() != 0)
            {
                LTiposAmenazas = TipAmenQuery.ToList();
            }
            return LTiposAmenazas;
        }


    }
}
